import {
  LESS_THAN,
  BIGGER_THAN,
  EQUAL,
  TCOMPARES,
  DATA_TYPE,
  COLORS_TXT,
} from './constant';

export type TEqualFunc = (a: any, b: any) => boolean;
export const defaultEaquals: TEqualFunc = (a: any, b: any) => {
  if (typeof a === 'number' && typeof b === 'number') {
    if (Number.isNaN(a) && Number.isNaN(b)) {
      return true;
    }
  }
  return a === b;
};

export type TCompareFunc = (a: any, b: any) => TCOMPARES;
export const defaultCompare: TCompareFunc = (a: any, b: any) => {
  if (a === b) {
    return EQUAL;
  } else {
    return a < b ? LESS_THAN : BIGGER_THAN;
  }
};

const NaNSymbol = Symbol('NaN');

export const encodeVal = (value) => {
  return Number.isNaN(value) ? NaNSymbol : value;
};

export const decodeVal = (value) => {
  return value === NaNSymbol ? NaN : value;
};

export function hashConversion(key: any, hashNumber = 37) {
  const indexType = Object.prototype.toString.call(key);
  const keyToString = `${indexType}_${indexType === DATA_TYPE.symbol ? key.toString() : key}`;
  let keyCode = 0;

  for(let item of keyToString) {
    keyCode += (item.codePointAt(0) ?? NaN);
  }
  let keyHash = keyCode % hashNumber;
  return keyHash;
}
export function djb2HashCode(key: any) {
  const indexType = Object.prototype.toString.call(key);
  const keyToString = `${indexType}_${indexType === DATA_TYPE.symbol ? key.toString() : key}`;
  let hash = 5381;
  
  for (let char of keyToString) {
    hash = hash * 33 + char.charCodeAt(0);
  }

  return hash % 1013;
}

export const swap = (array: any[], indexA: number, indexB: number) => {
  const temp = array[indexA];

  array[indexA] = array[indexB];
  array[indexB] = temp;
};

export const initializeVertexesColor = (vertexes: any[]) => {
  const colors: Map<any, COLORS_TXT> = new Map();

  for (let v of vertexes) {
    colors.set(v, COLORS_TXT.WHITE);
  }

  return colors;
};
